package org.iabako.client.ui.form.business.payment;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTMLPanel;
import org.iabako.client.config.page.PageEnum;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.tools.Messages;
import org.iabako.client.ui.form.AbstractForm;
import org.iabako.client.ui.layout.field.IField;
import org.iabako.client.ui.layout.field.LabelText;
import org.iabako.client.ui.layout.widget.datatable.CustomColumnDefinition;
import org.iabako.client.ui.layout.widget.datatable.CustomColumnEventHandler;
import org.iabako.client.ui.layout.widget.dialogbox.IabakoDialogBox;
import org.iabako.client.ui.layout.widget.payment.PaymentResume;
import org.iabako.client.ui.layout.widget.payment.PaymentTable;
import org.iabako.client.ui.layout.widget.tooltip.TooltipListener;
import org.iabako.client.ui.layout.widget.validation.ValidationMessage;
import org.iabako.client.user.AuthenticateUserProvider;
import org.iabako.shared.entity.business.AbstractEntity;
import org.iabako.shared.entity.enumeration.NotificationType;
import org.iabako.shared.entity.enumeration.TrackingType;
import org.iabako.shared.iservice.business.SaleServiceAsync;

import java.util.List;

/**
 * Created by jose on 11/09/14.
 */
public abstract class ListPaymentsForm extends AbstractForm {

    interface MyUiBinder extends UiBinder<HTMLPanel, ListPaymentsForm> {
    }

    protected MyUiBinder binderListPaymentsForm = GWT.create(MyUiBinder.class);

    protected final SaleServiceAsync saleServiceAsync = SaleServiceAsync.Util.getInstance();

    @UiField
    public HTMLPanel paymentsPanel;
    @UiField
    public HTMLPanel installmentsPanel;
    @UiField
    public PaymentResume paymentResume;
    @UiField
    public LabelText addPaymentAction;
    @UiField
    public LabelText addInstallmentAction;
    @UiField
    protected HTMLPanel undefinedInstallmentsRecapPanel;
    @UiField
    protected LabelText undefinedInstallmentsNote;
    @UiField
    protected LabelText undefinedInstallmentsStopCreation;

    protected CustomColumnDefinition paymentToInstallmentAction;
    protected CustomColumnDefinition installmentToPaymentAction;

    protected PaymentTable payments;
    protected PaymentTable installments;

    public boolean disableWarningMessage;

    public ListPaymentsForm() {

        initWidget(binderListPaymentsForm.createAndBindUi(this));

        Element divIconPayment = DOM.createDiv();
        divIconPayment.setClassName("transfertorightdisable");
        paymentToInstallmentAction = new CustomColumnDefinition("columnSminus", "columnSminus tdtransfertorightdisable", "transfer_payment_to_installment_title_disable", divIconPayment, new NoActionHandler());

        Element divIconInstallments = DOM.createDiv();
        divIconInstallments.setClassName("transfertoleftdisable");
        installmentToPaymentAction = new CustomColumnDefinition("columnSminus", "columnSminus tdtransfertoleftdisable", "transfer_installment_to_payment_title_disable", divIconInstallments, new NoActionHandler());

        setHandlers();
    }

    private void setHandlers() {
        addPaymentAction.getLabel().addClickHandler(new AddActionHandler(this, false));
        addInstallmentAction.getLabel().addClickHandler(new AddActionHandler(this, true));
    }

    private class AddActionHandler implements ClickHandler {

        ListPaymentsForm listPaymentsForm;
        boolean isInstallment;

        private AddActionHandler(ListPaymentsForm salePaymentsForm, boolean isInstallment) {
            this.listPaymentsForm = salePaymentsForm;
            this.isInstallment = isInstallment;
        }

        public void onClick(ClickEvent event) {
            if (disableWarningMessage) {
                if (isInstallment) {
                    NavigationController.getInstance().goTo(PageEnum.InstallmentMake, listPaymentsForm);
                } else {
                    NavigationController.getInstance().goTo(PageEnum.PaymentMake, listPaymentsForm);
                }
                return;
            }

            String confirmMessageKey = isInstallment ? "sale_installments_creation_confirm_question" : "sale_payments_creation_confirm_question";
            String confirmMessageTitle = isInstallment ? "sale_installments_creation_confirm_title" : "sale_payments_creation_confirm_title";

            IabakoDialogBox iabakoDialogBox = new IabakoDialogBox(confirmMessageTitle, confirmMessageKey, true, "payment_add_confirm") {
                @Override
                protected void customConfirmButtonHandler() {
                    if (isInstallment) {
                        NavigationController.getInstance().goTo(PageEnum.InstallmentMake, listPaymentsForm);
                    } else {
                        NavigationController.getInstance().goTo(PageEnum.PaymentMake, listPaymentsForm);
                    }
                }
            };

            iabakoDialogBox.setCloseOnlySimplePopup(true);

            NavigationController.getInstance().show(iabakoDialogBox);
        }
    }

    public class NoActionHandler extends CustomColumnEventHandler {
        @Override
        public void onBrowserEvent(Event event) {
            event.stopPropagation();
            return;
        }
        @Override
        public CustomColumnEventHandler getClone() {
            return new NoActionHandler();
        }
    }

    public class TransferHandler extends CustomColumnEventHandler {

        boolean paymentToInstallment;
        boolean installmentToPayment;
        ListPaymentsForm listPaymentsForm;

        public TransferHandler(ListPaymentsForm listPaymentsForm, boolean paymentToInstallment, boolean installmentToPayment) {
            super();
            this.listPaymentsForm = listPaymentsForm;
            this.paymentToInstallment = paymentToInstallment;
            this.installmentToPayment = installmentToPayment;
        }

        @Override
        public CustomColumnEventHandler getClone() {
            TransferHandler transferHandler = new TransferHandler(listPaymentsForm, paymentToInstallment, installmentToPayment);
            transferHandler.setDivElement(divElement);
            return transferHandler;
        }

        public void onBrowserEvent(Event event) {
            event.stopPropagation();

            Long id = Long.parseLong(divElement.getId().replace("custom_action_", ""));
            final ValidationMessage validationMessage = ValidationMessage.getFirstFromDOM();

            if (paymentToInstallment) {
                saleServiceAsync.paymentToInstallment(id, new IabakoAsyncCallback<Void>() {
                    public void onSuccess(Void result) {
                        refreshPayments();
                        refreshInstallments();
                        customSuccessTransferAction();

                        AuthenticateUserProvider.getNotificationPanel().refresh(NotificationType.futureInstallments, NotificationType.newPastInstallments);
                        AuthenticateUserProvider.getTrackingPanel().refresh(TrackingType.paymentReceivedToInstallment);

                        validationMessage.showSuccessMessage("validation_sale_payment_to_installment_success");
                        super.onSuccess(result);
                    }
                });
            } else if (installmentToPayment) {

                NavigationController.getInstance().goTo(PageEnum.PaymentTransfer, listPaymentsForm, id + "");
            }
        }
    }

    protected void enableLastCustomActionForPayment() {
        List<TableCellElement> customCells = payments.getCustomCellActions();
        if (customCells.size() > 0) {
            customCells.get(customCells.size() - 1).setClassName(customCells.get(0).getClassName() + " tdtransfertoright");
            customCells.get(customCells.size() - 1).getFirstChildElement().setClassName("transfertoright");

            //add tooltip event
            DOM.sinkEvents(customCells.get(customCells.size() - 1).getFirstChildElement(), Event.MOUSEEVENTS);
            DOM.setEventListener(customCells.get(customCells.size() - 1).getFirstChildElement(), new TooltipListener(Messages.getLabel("transfer_payment_to_installment_title")));

            //add action event
            TransferHandler transferHandler = new TransferHandler(this, true, false);
            transferHandler.setDivElement(customCells.get(customCells.size() - 1).getFirstChildElement());
            DOM.sinkEvents(customCells.get(customCells.size() - 1), Event.ONCLICK);
            DOM.setEventListener(customCells.get(customCells.size() - 1), transferHandler);
        }
    }

    protected void enableFirstCustomActionForInstallment() {
        List<TableCellElement> customCells = installments.getCustomCellActions();
        if (customCells.size() > 0) {
            customCells.get(0).setClassName(customCells.get(0).getClassName() + " tdtransfertoleft");
            customCells.get(0).getFirstChildElement().setClassName("transfertoleft");

            //add tooltip event
            DOM.sinkEvents(customCells.get(0).getFirstChildElement(), Event.MOUSEEVENTS);
            DOM.setEventListener(customCells.get(0).getFirstChildElement(), new TooltipListener(Messages.getLabel("transfer_installment_to_payment_title")));

            //add action event
            TransferHandler transferHandler = new TransferHandler(this, false, true);
            transferHandler.setDivElement(customCells.get(0).getFirstChildElement());
            DOM.sinkEvents(customCells.get(0), Event.ONCLICK);
            DOM.setEventListener(customCells.get(0), transferHandler);
        }
    }

    protected abstract void customSuccessTransferAction();

    protected abstract void getPaymentsAndInstallments();


    public void refreshPayments() {
        payments.refreshSearch();
    }

    public void refreshInstallments() {
        installments.refreshSearch();
    }

    public PaymentTable getPaymentTable() {
        return payments;
    }

    public PaymentTable getInstallmentTable() {
        return installments;
    }

    @Override
    protected List<IField> getMandatoryFields() {
        return null;
    }

    @Override
    protected AbstractEntity getEntity() {
        return null;
    }

    @Override
    public boolean validate() {
        return false;
    }
}
